package com.hm.email.util;

import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.hm.common.exception.ServiceException;
import com.hm.email.vo.EmailVo;

/**
 * @author shishun.wang
 * @date 下午5:17:54 2016年6月16日
 * @version 1.0
 * @describe
 */
@Component
public class EmailFactory {

	@Autowired
	private MailProperties mailProperties;
	
	@Autowired
	private JavaMailSender javaMailSender;

	private String contentType = "text/html;charset=utf-8";

	/**
	 * 发送/抄送邮件
	 * 
	 * @param email
	 * @throws AddressException
	 * @throws MessagingException
	 */
	@Async
	public void send(EmailVo email) throws AddressException, MessagingException {
		final MimeMessage message = copyToSetting(email);
		// 设置邮件内容
		message.setContent(email.getContent(), contentType);
		// 发送
		javaMailSender.send(message);
	}

	/**
	 * 发送/抄送邮件 - 附件
	 * 
	 * @param email
	 * @param emailModels
	 * @throws AddressException
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
	@Async
	public void send(EmailVo email, EmailModel[] emailModels)
			throws AddressException, MessagingException, UnsupportedEncodingException {
		final MimeMessage message = copyToSetting(email);
		// 设置邮件内容
		accessorySetting(email, emailModels, message);
		// 发送
		javaMailSender.send(message);
	}

	/**
	 * @param email
	 * @param files
	 * @param message
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
	private void accessorySetting(EmailVo email, EmailModel[] emailModels, final MimeMessage message)
			throws MessagingException, UnsupportedEncodingException {
		Multipart multipart = new MimeMultipart();
		{
			BodyPart bodyPart = new MimeBodyPart();
			{// html 文本内容描述
				bodyPart.setContent(email.getContent(), contentType);
				multipart.addBodyPart(bodyPart);
			}
			if (null != emailModels) {
				for (EmailModel emailModel : emailModels) {
					bodyPart = new MimeBodyPart();
					{
						bodyPart.setDataHandler(new DataHandler(new FileDataSource(emailModel.getFile())));
						bodyPart.setFileName(MimeUtility.encodeText(emailModel.getName()));
						multipart.addBodyPart(bodyPart);
					}
				}
			}
		}
		message.setContent(multipart);
	}

	/**
	 * @param email
	 * @return
	 * @throws MessagingException
	 * @throws AddressException
	 */
	private MimeMessage copyToSetting(EmailVo email) throws MessagingException, AddressException {
		// 创建mime类型邮件
		final MimeMessage message = javaMailSender.createMimeMessage();	
		// 设置发信人
		message.setFrom(new InternetAddress(mailProperties.getUsername()));
		// 设置收件人
		if(CollectionUtils.isEmpty(email.getRecipient())){
			throw ServiceException.warn("收件人不能为null");
		}
		message.setRecipient(RecipientType.TO, new InternetAddress(email.getRecipient().get(0)));

		List<String> copyTos = email.getCopyTo();
		if (!CollectionUtils.isEmpty(copyTos)) {
			// 为每个邮件接收者创建一个地址
			Address[] copyToAdresses = new InternetAddress[copyTos.size()];
			for (int i = 0; i < copyTos.size(); i++) {
				copyToAdresses[i] = new InternetAddress(copyTos.get(i));
			}
			// 将抄送者信息设置到邮件信息中，注意类型为Message.RecipientType.CC
			message.setRecipients(Message.RecipientType.CC, copyToAdresses);
		}

		// 设置主题
		message.setSubject(email.getTheme());
		return message;
	}

	/**
	 * 群发邮件 - 附件
	 * 
	 * @param recipients
	 * @param subject
	 * @param content
	 * @param emailModels
	 * @throws AddressException
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
	public void send(List<String> recipients, String subject, Object content, EmailModel[] emailModels)
			throws AddressException, MessagingException, UnsupportedEncodingException {
		final MimeMessage message = massSetting(recipients, subject);
		// 设置邮件内容
		Multipart multipart = new MimeMultipart();
		{
			BodyPart bodyPart = new MimeBodyPart();
			{// html 文本内容描述
				bodyPart.setContent(content.toString(), contentType);
				multipart.addBodyPart(bodyPart);
			}
			if (null != emailModels) {
				for (EmailModel emailModel : emailModels) {
					bodyPart = new MimeBodyPart();
					{
						bodyPart.setDataHandler(new DataHandler(new FileDataSource(emailModel.getFile())));
						bodyPart.setFileName(MimeUtility.encodeText(emailModel.getName()));
						multipart.addBodyPart(bodyPart);
					}
				}
			}
		}
		message.setContent(multipart);

		// 发送
		javaMailSender.send(message);
	}

	/**
	 * @param recipients
	 * @param subject
	 * @return
	 * @throws MessagingException
	 * @throws AddressException
	 */
	private MimeMessage massSetting(List<String> recipients, String subject)
			throws MessagingException, AddressException {
		// 创建mime类型邮件
		final MimeMessage message = javaMailSender.createMimeMessage();
		// 设置发信人
		message.setFrom(new InternetAddress(mailProperties.getUsername()));
		// 设置收件人们
		final int num = recipients.size();
		InternetAddress[] addresses = new InternetAddress[num];
		for (int i = 0; i < num; i++) {
			addresses[i] = new InternetAddress(recipients.get(i));
		}
		message.setRecipients(RecipientType.TO, addresses);
		// 设置主题
		message.setSubject(subject);
		return message;
	}

	/**
	 * 群发邮件
	 * 
	 * @param recipients
	 *            收件人们
	 * @param subject
	 *            主题
	 * @param content
	 *            内容
	 * @throws AddressException
	 * @throws MessagingException
	 */
	public void send(List<String> recipients, String subject, Object content)
			throws AddressException, MessagingException {
		final MimeMessage message = massSetting(recipients, subject);
		// 设置邮件内容
		message.setContent(content.toString(), contentType);
		// 发送
		javaMailSender.send(message);
	}
	
}
